﻿using System;
using System.IO;
using Ooaavee.Scripting.Remoting;

namespace Ooaavee.Scripting
{
    /// <summary>
    /// The scripting context provides information about and functionality for a script.
    /// </summary>
    [Serializable]
    public sealed class ScriptingContext : ICloneable
    {

        #region Private fields

        private References _references;
        private static ScriptingContext _default;

        #endregion

        /// <summary>
        /// Gets and sets the fully qualified type name of the remote script base class.
        /// </summary>
        public string RemoteScriptBaseClassFullName { set; get; }

        /// <summary>
        /// Gets and sets the script programming language; the default value is <see cref="Ooaavee.Scripting.Language.CSharp"/>.
        /// </summary>
        public Language Language { set; get; }

        /// <summary>
        /// Gets and sets the working directory; the default value is the current user's temporary folder.
        /// </summary>
        public DirectoryInfo WorkingDirectory { set; get; }

        /// <summary>
        /// Gets references.
        /// </summary>
        public References References
        {
            get
            {
                if (_references == null)
                {
                    _references = new References();
                }
                return _references;
            }
            private set { _references = value; }
        }

        /// <summary>
        /// Gets the default scripting context.
        /// </summary>
        public static ScriptingContext Default
        {
            get
            {
                if (_default == null)
                {
                    _default = CreateDefault();
                }
                return _default;
            }
        }

        /// <summary>
        /// Creates the default scripting context.
        /// </summary>
        /// <returns>the default scripting context</returns>
        public static ScriptingContext CreateDefault()
        {
            ScriptingContext context = new ScriptingContext();

            context.RemoteScriptBaseClassFullName = typeof(RemoteScript).FullName;

            context.Language = Language.CSharp;

            context.WorkingDirectory = new DirectoryInfo(Path.GetTempPath());

            foreach (Reference reference in References.GetDefault())
            {
                context.References.Add(reference);
            }                    
            
            return context;
        }

        /// <summary>
        /// Returns a deep copy of this object.
        /// </summary>
        /// <returns>a deep copy</returns>
        object ICloneable.Clone()
        {
            ScriptingContext clone = new ScriptingContext();
            clone.RemoteScriptBaseClassFullName = RemoteScriptBaseClassFullName;
            clone.Language = Language;
            clone.WorkingDirectory = WorkingDirectory;
            clone.References = (References) ((ICloneable) References).Clone();
            return clone;
        }
    }
}